		TITLE	ORDER - Copyright (c) SLR Systems 1994

		INCLUDE	MACROS
		INCLUDE	SEGMENTS
		INCLUDE	GROUPS
		INCLUDE	CLASSES

		PUBLIC	ORDER_SEGMENTS

if	fg_rom

		PUBLIC	STORE_DEBUG_CLASS

endif


		.DATA

		EXTERNDEF	SEG_COMBINE:BYTE,PACKTYPE:BYTE,FILE_PLINK_FLAGS:BYTE,SEG32_FLAGS:BYTE

		EXTERNDEF	COM_TABLE:DWORD,PACKCODE:DWORD,PACKDATA:DWORD,PACKSIZE:DWORD,SEGMENT_COUNT:DWORD
		EXTERNDEF	ZERO_LENGTH_SEGMENTS:DWORD,DATA_DEFAULTS_MASK:DWORD,DATA_DEFAULTS:DWORD,FLAG_0C:DWORD
		EXTERNDEF	PACK_TEMP_WORD:DWORD,CLASS_DEBTYP_GINDEX:DWORD,CLASS_DEBSYM_GINDEX:DWORD,FIRST_CLASS_GINDEX:DWORD
		EXTERNDEF	FIRST_GROUP_GINDEX:DWORD,LAST_GROUP_GINDEX:DWORD,_TEXT_SEGMENT_GINDEX:DWORD,SEG_NAME_LINDEX:DWORD
		EXTERNDEF	CLASS_NAME_LINDEX:DWORD,CURNMOD_GINDEX:DWORD,FIRST_SEGMENT_GINDEX:DWORD,LAST_SEGMENT_GINDEX:DWORD
		EXTERNDEF	FIRST_DIF_SEG_GINDEX:DWORD,LAST_DIF_SEG_GINDEX:DWORD,FIRST_CODE_GROUP_GINDEX:DWORD
		EXTERNDEF	FIRST_DATA_GROUP_GINDEX:DWORD,LAST_DATA_GROUP_GINDEX:DWORD,FIRST_CODE_SEGMENT_GINDEX:DWORD
		EXTERNDEF	LAST_CODE_SEGMENT_GINDEX:DWORD,FIRST_DATA_SEGMENT_GINDEX:DWORD,LAST_DATA_SEGMENT_GINDEX:DWORD
		EXTERNDEF	APPLOADER_SEGMENT_GINDEX:DWORD,NULL_TEXT_SEGMOD_GINDEX:DWORD,MOD_SECTION_GINDEX:DWORD
		EXTERNDEF	FILE_SECTION_GINDEX:DWORD,DGROUP_GINDEX:DWORD,LAST_CODE_GROUP_GINDEX:DWORD,SLR_VECTORS:DWORD
		EXTERNDEF	LAST_DATA_GROUP_GINDEX:DWORD,BEGDATA_CLASS_GINDEX:DWORD,BSS_CLASS_GINDEX:DWORD
		EXTERNDEF	STACK_CLASS_GINDEX:DWORD,DEBTYP_CLASS_GINDEX:DWORD,DEBNAM_CLASS_GINDEX:DWORD,tls_CLASS_GINDEX:DWORD
		EXTERNDEF	CLASS_DEBNAM_GINDEX:DWORD,DEBSYM_CLASS_GINDEX:DWORD,SEG_LEN:DWORD,VECTOR_TABLE_ADDRESS:DWORD
		EXTERNDEF	SLR_CODE_CLASS:DWORD,DOSSEG_STRUC:DWORD,SEGMENT_TABLE:DWORD,SLR_SCODE_CLASS:DWORD
		EXTERNDEF	SEGMENT_TABLE_PTR:DWORD,FIRST_MODULE_GINDEX:DWORD

		EXTERNDEF	CODE_TPTR:TPTR_STRUCT,_TEXT_TPTR:TPTR_STRUCT,DEBTYP_TPTR:TPTR_STRUCT,BSS_TPTR:TPTR_STRUCT
		EXTERNDEF	BEGDATA_TPTR:TPTR_STRUCT,STACK_TPTR:TPTR_STRUCT

		EXTERNDEF	CLASS_GARRAY:STD_PTR_S,SEGMENT_GARRAY:STD_PTR_S,GROUP_GARRAY:STD_PTR_S,SEGMOD_GARRAY:STD_PTR_S

		EXTERNDEF	CASE_STRING_COMPARE:DWORD


		.CODE	MIDDLE_TEXT

		EXTERNDEF	ALIGN_SEGS:PROC,ABSOLUTE_ORDER:PROC,WARN_RET:PROC,ERR_RET:PROC,SET_GROUPS:PROC,ERR_ASCIZ_RET:PROC
		EXTERNDEF	WARN_ASCIZ_RET:PROC,DEFINE_SEGMOD_0:PROC,DO_ECX_ALIGN:PROC
		EXTERNDEF	MAKE_TPTR_LINDEX:PROC,INIT_LOCAL_STORAGE:PROC,RELEASE_LOCAL_STORAGE:PROC

		EXTERNDEF	GRP_COD_DAT_ERR:ABS,OS2_FLAG_CONFLICT_ERR:ABS,CODEPACK_ERR:ABS,GRP_OVERLAP_ERR:ABS,DATAPACK_ERR:ABS
		EXTERNDEF	TOO_MANY_SEGS_ERR:ABS,USE32_USE16_ERR:ABS


ORDER_SEGMENTS	PROC
		;
		;SPECIAL DOSSEG ORDERING, NEED TO STICK CLASSES IN A SPECIFIC
		;ORDER
		;DEFINE CLASSES...
		;

		CALL	LINK_IN_4_LISTS 	;SPEC ORDER IF DOSSEG OR REORDER...
		;
		;IF DOSSEG ORDERING, FIX DGROUP STUFF
		;
		BITT	DOSSEG_FLAG
		JZ	L2$
		CALL	DOSSEG_ORDER		;PUTS DGROUP LAST IF REORDERING
L2$:

		BITT	OUTPUT_SEGMENTED
		JZ	L25$

		BITT	REORDER_ALLOWED
		JZ	L25$
		CALL	FINE_TUNE_ORDERING	;
L25$:

		CALL	LINK_4_TOGETHER 	;CONNECT TOGETHER

		BITT	REORDER_ALLOWED
		JNZ	L29$			;REORDERING ALLOWED, SKIP
if	any_overlays
		BITT	DOING_OVERLAYS
		JNZ	L29$
endif
		CALL	SET_GROUPS		;ADJUST FIRST AND LAST SEGMENTS...
		CALL	FIX_MIDGROUPS		;JAM INTERMEDIATE SEGS INTO GROUP
L29$:


		BITT	OUTPUT_SEGMENTED
		JZ	L30$

		CALL	DGROUP_FLAGS		;FIX FLAGS ON ALL DGROUP SEGS
		BITT	OS2_FLAGS_DIFFERED
		JZ	L30$
		CALL	MAKE_OS2_MATCH		;FIX OTHER FLAGS ALSO
L30$:
		;
		;NOW SEGMENTS IN SINGLE LIST (EXCEPT DEBUG STUFF)
		;ADD DEBUG STUFF TO LIST
		;
		CALL	LINK_IN_DEBUGS		;
		RET

ORDER_SEGMENTS	ENDP


DO_NULLS_DOSSEG PROC	NEAR
		;
		;IF _TEXT : CODE EXISTS, STICK 16 BYTES AHEAD OF IT...
		;
		MOV	ESI,_TEXT_SEGMENT_GINDEX

		TEST	ESI,ESI
		JZ	L9$
		BITT	NULLSDOSSEG_FLAG
		JZ	L9$
		CONVERT	ESI,ESI,SEGMENT_GARRAY
		ASSUME	ESI:PTR SEGMENT_STRUCT

		TEST	[ESI]._SEG_32FLAGS,MASK SEG32_NONZERO
		JZ	L9$

		MOV	EAX,[ESI]._SEG_LAST_SEGMOD_GINDEX
		MOV	EBX,[ESI]._SEG_FIRST_SEGMOD_GINDEX
		PUSHM	EAX,EBX
		XOR	EAX,EAX
		MOV	[ESI]._SEG_FIRST_SEGMOD_GINDEX,EAX
		MOV	[ESI]._SEG_LAST_SEGMOD_GINDEX,EAX
		;
		;SET UP TO FIND _TEXT-CODE SEGMENT
		;
		CALL	INIT_LOCAL_STORAGE
		;
		MOV	EAX,FIRST_MODULE_GINDEX
		MOV	CURNMOD_GINDEX,EAX

		MOV	EAX,OFF CODE_TPTR
		CALL	MAKE_TPTR_LINDEX
		MOV	CLASS_NAME_LINDEX,EAX
		;
		MOV	EAX,OFF _TEXT_TPTR
		CALL	MAKE_TPTR_LINDEX
		MOV	SEG_NAME_LINDEX,EAX
		;
		MOV	WPTR SEG_COMBINE,202H	;WORD PUBLIC PER MULTIPAD C7.0
		XOR	EAX,EAX
if	any_overlays
		MOV	MOD_SECTION_GINDEX,AX
		MOV	FILE_PLINK_FLAGS,AL
		MOV	FILE_SECTION_GINDEX,AX
endif
		MOV	SEG32_FLAGS,AL		;DON'T FORCE USE16/USE32

		CALL	DEFINE_SEGMOD_0		;EAX IS SEGMOD, ECX IS PHYS - 0 LENGTH SO SECTION MATCHES OTHER _TEXT SEGMODS
		ASSUME	ECX:PTR SEGMOD_STRUCT

		MOV	ESI,_TEXT_SEGMENT_GINDEX
		POP	EBX
		CONVERT	ESI,ESI,SEGMENT_GARRAY
		ASSUME	ESI:PTR SEGMENT_STRUCT

		MOV	NULL_TEXT_SEGMOD_GINDEX,EAX
		POP	EDX

		MOV	[ECX]._SM_NEXT_SEGMOD_GINDEX,EBX
		XOR	EAX,EAX

		MOV	[ESI]._SEG_LAST_SEGMOD_GINDEX,EDX
		MOV	CURNMOD_GINDEX,EAX

		CALL	RELEASE_LOCAL_STORAGE
L9$:
		RET

		ASSUME	ESI:NOTHING

DO_NULLS_DOSSEG ENDP


DOSSEG_ORDER	PROC	NEAR
		;
		;SPECIAL ORDERING REQUIREMENTS...
		;
		;FIRST, FIND DGROUP
		;
		CALL	DO_NULLS_DOSSEG

		MOV	EAX,DGROUP_GINDEX
		MOV	EBX,OFF DOSSEG_STUFF

		OR	EAX,EAX
		JZ	L9$
		;
		;SET UP DOSSEG_STRUC
		;
		MOV	ECX,4
		MOV	EDI,OFF DOSSEG_STRUC
		XOR	EDX,EDX

L0$:
		MOV	ESI,[EBX]
		ADD	EBX,4

		MOV	[EDI+8],EDX		;FIRST AND LAST SEGMENTS THIS CLASS-TYPE
		MOV	[EDI+12],EDX

		MOV	EAX,[ESI]
		MOV	[EDI+4],EDX

		MOV	[EDI],EAX
		ADD	EDI,16

		DEC	ECX
		JNZ	L0$
		;
		;
		;OK, LINK SEGMENTS INTO 4 LISTS,
		; 1.	CLASS == BEGDATA
		; 2.	CLASS == BSS
		; 3.	CLASS == STACK
		; 4.	ALL OTHERS
		;
		MOV	ESI,DGROUP_GINDEX
		CONVERT	ESI,ESI,GROUP_GARRAY
		ASSUME	ESI:PTR GROUP_STRUCT
		XOR	EAX,EAX

		MOV	[ESI]._G_LAST_SEG_GINDEX,EAX
		LEA	ESI,[ESI + GROUP_STRUCT._G_FIRST_SEG_GINDEX-SEGMENT_STRUCT._SEG_NEXT_SEG_GINDEX]
		ASSUME	ESI:PTR SEGMENT_STRUCT

L1$:
		XOR	EAX,EAX
		MOV	ECX,[ESI]._SEG_NEXT_SEG_GINDEX

		MOV	[ESI]._SEG_NEXT_SEG_GINDEX,EAX
		MOV	ESI,ECX

		TEST	ECX,ECX
		JZ	L5$
		;
		;CHECK TO SEE WHICH LIST THIS GOES IN...
		;
		CONVERT	ESI,ESI,SEGMENT_GARRAY
		ASSUME	ESI:PTR SEGMENT_STRUCT

		MOV	EBX,OFF DOSSEG_STRUC
		MOV	EDX,[ESI]._SEG_CLASS_GINDEX
		MOV	EAX,3
L2$:
		MOV	EDI,[EBX]

		CMP	EDI,EDX
		JZ	L3$

		ADD	EBX,16
		DEC	EAX

		JNZ	L2$
L3$:

		;
		;ADD THIS TO THE LINKED LIST...
		;
		MOV	EAX,[EBX+12]
		MOV	[EBX+12],ECX

		TEST	EAX,EAX 		;LAST SEGMENT EXISTS?
		JZ	L45$			;NOPE

		CONVERT	EAX,EAX,SEGMENT_GARRAY
		ASSUME	EAX:PTR SEGMENT_STRUCT

		MOV	[EAX]._SEG_NEXT_SEG_GINDEX,ECX
		JMP	L1$

L9$:
		RET

L45$:
		MOV	[EBX+8],ECX
		JMP	L1$

L5$:
		;
		;NOW MERGE THOSE 4 LISTS INTO 1-4-2-3
		;
		MOV	ESI,DGROUP_GINDEX
		CONVERT	ESI,ESI,GROUP_GARRAY
		ASSUME	ESI:PTR GROUP_STRUCT

		MOV	EAX,OFF DOSSEG_STRUC
		CALL	LINK_TO_DGROUP

		MOV	EAX,OFF DOSSEG_STRUC+3*16
		CALL	LINK_TO_DGROUP

		MOV	EAX,OFF DOSSEG_STRUC+1*16
		CALL	LINK_TO_DGROUP

		MOV	EAX,OFF DOSSEG_STRUC+2*16
		CALL	LINK_TO_DGROUP

		RET

DOSSEG_ORDER	ENDP

		ASSUME	EAX:NOTHING

LINK_TO_DGROUP	PROC	NEAR
		;
		;
		;
		MOV	ECX,[EAX+8]		;ANY SEGS THIS CLASS?
		MOV	EDX,[EAX+12]

		TEST	ECX,ECX
		JZ	L9$			;NOPE, SKIP

		MOV	EAX,[ESI]._G_LAST_SEG_GINDEX	;ANY SEGS THIS GROUP?
		MOV	[ESI]._G_LAST_SEG_GINDEX,EDX

		TEST	EAX,EAX
		JZ	L5$			;NOPE, DO FIRST

		CONVERT	EAX,EAX,SEGMENT_GARRAY
		ASSUME	EAX:PTR SEGMENT_STRUCT

		MOV	[EAX]._SEG_NEXT_SEG_GINDEX,ECX
L9$:
		RET

L5$:
		MOV	[ESI]._G_FIRST_SEG_GINDEX,ECX
		RET

LINK_TO_DGROUP	ENDP


DGROUP_FLAGS	PROC	NEAR
		;
		;MAKE DGROUP SEGMENT FLAGS MATCH FLAGS BYTE AS SPECIFIED BY
		;
		TEST	DATA_DEFAULTS_MASK,MASK SR_MULTIPLE
		JNZ	L2$

		MOV	EAX,DATA_DEFAULTS
		AND	EAX,MASK SR_SHARED
		XOR	EAX,MASK SR_SHARED
		SHR	EAX,SR_SHARED
		INC	EAX
		TEST	DATA_DEFAULTS_MASK,MASK SR_SHARED
		JNZ	L3$
		;
		;
		;
		MOV	EAX,MASK APPMULTI	;NONSHARED STANDARD FOR EXE
		TEST	FLAG_0C,MASK APPTYPE
		JZ	L3$
		MOV	EAX,MASK APPSOLO 	;SHARED STANDARD FOR DLL
		JMP	L3$

L2$:
		MOV	EAX,DATA_DEFAULTS
		AND	EAX,MASK SR_MULTIPLE
		SHR	EAX,SR_MULTIPLE
L3$:
		OR	FLAG_0C,EAX
		;
		;MAKE SURE DGROUP 'SHARED' BIT MATCHES FLAG_0C APPSOLO BIT
		;
		MOV	ESI,DGROUP_GINDEX

		TEST	ESI,ESI
		JZ	L9$

		CONVERT	ESI,ESI,GROUP_GARRAY
		ASSUME	ESI:PTR GROUP_STRUCT

		MOV	EAX,FLAG_0C
		AND	EAX,MASK APPSOLO
		SHL	EAX,SR_SHARED-APPSOLO
		XOR	EAX,[ESI]._G_OS2_FLAGS
		AND	EAX,MASK SR_SHARED
		JZ	L9$
		;
		;NEED TO FLIP BIT
		;
		XOR	[ESI]._G_OS2_FLAGS,MASK SR_SHARED
		MOV	EDI,[ESI]._G_LAST_SEG_GINDEX
		MOV	ESI,[ESI]._G_FIRST_SEG_GINDEX
		JMP	L5$

L4$:
		MOV	ECX,ESI
		CONVERT	ESI,ESI,SEGMENT_GARRAY
		ASSUME	ESI:PTR SEGMENT_STRUCT

		XOR	[ESI]._SEG_OS2_FLAGS,MASK SR_SHARED
		MOV	ESI,[ESI]._SEG_NEXT_SEG_GINDEX

		CMP	ECX,EDI
		JZ	L9$
L5$:
		TEST	ESI,ESI
		JNZ	L4$
L9$:
		RET

DGROUP_FLAGS	ENDP


STORE_DEBUG_CLASS	PROC	NEAR
		;
		;DS:SI IS CLASS, STORE GINDEX...
		;
		BITT	CODEVIEW_FLAG		;SKIP IF NO CV INFO WANTED
		JZ	L9$

		CMP	DEBTYP_CLASS_GINDEX,ECX
		JZ	L3$
		;
		;IF NOT DEBTYP, MUST BE DEBSYM...
		;
		CMP	DEBSYM_CLASS_GINDEX,ECX
		JZ	L2$

		MOV	CLASS_DEBNAM_GINDEX,ECX
		RET


L2$:
		MOV	CLASS_DEBSYM_GINDEX,ECX
		RET

L3$:
		MOV	CLASS_DEBTYP_GINDEX,ECX
L9$:
		RET

STORE_DEBUG_CLASS	ENDP


LINK_IN_DEBUGS	PROC	NEAR
		;
		;ES:DI IS LAST SEGMENT, LINK DEBUG SEGMENTS HERE...
		;
		MOV	EAX,CLASS_DEBTYP_GINDEX
		CALL	LINK_DEBUG_SEGMENT
		MOV	EAX,CLASS_DEBSYM_GINDEX
		CALL	LINK_DEBUG_SEGMENT
		MOV	EAX,CLASS_DEBNAM_GINDEX

LINK_DEBUG_SEGMENT:
		;
		;
		;
		TEST	EAX,EAX
		JZ	L9$
		CONVERT	EAX,EAX,CLASS_GARRAY
		ASSUME	EAX:PTR CLASS_STRUCT
		;
		;SEE IF THIS CLASS ACTUALLY HAS A SEGMENT
		;
		MOV	ECX,[EAX]._C_LAST_SEG_GINDEX
		MOV	EAX,[EAX]._C_FIRST_SEG_GINDEX
		JMP	LINK_SEGMENTS

L9$:
		RET

LINK_IN_DEBUGS	ENDP


FINE_TUNE_ORDERING	PROC	NEAR
		;
		;ORDER SEGMENTS WITHIN LIST ACCORDING TO OS2_FLAGS WORD
		;
		MOV	EAX,FIRST_CODE_SEGMENT_GINDEX
		CALL	FINE_TUNE_SEGMENTS
		MOV	LAST_CODE_SEGMENT_GINDEX,EAX

		MOV	EAX,FIRST_DATA_SEGMENT_GINDEX
		CALL	FINE_TUNE_SEGMENTS
		MOV	LAST_DATA_SEGMENT_GINDEX,EAX

		RET

FINE_TUNE_ORDERING	ENDP


FINE_TUNE_SEGMENTS	PROC	NEAR
		;
		;ORDER SEGMENTS IN THIS LIST ACCORDING TO OS2_FLAGS
		;
		MOV	EBX,EAX
		MOV	ESI,EAX

		TEST	EAX,EAX
		JZ	L9$

		MOV	ECX,EAX
		CONVERT	ESI,ESI,SEGMENT_GARRAY
		ASSUME	ESI:PTR SEGMENT_STRUCT

		MOV	EDX,[ESI]._SEG_OS2_FLAGS
		JMP	L3$

L1$:
		MOV	ECX,ESI
		CONVERT	ESI,ESI,SEGMENT_GARRAY
		ASSUME	ESI:PTR SEGMENT_STRUCT
		MOV	EAX,[ESI]._SEG_OS2_FLAGS
		CMP	EAX,EDX
		JNZ	L5$
L2$:
		ASSUME	EDI:PTR SEGMENT_STRUCT
		MOV	[EDI]._SEG_NEXT_SEG_GINDEX,ECX
L3$:
		;
		;CX IS SEGMENT GINDEX, DS:SI IS PHYSICAL
		;
		MOV	EBX,ECX
		MOV	EDI,ESI
		;
		;BX:DI IS NOW OLD SEGMENT
		;
L35$:
		MOV	ESI,[ESI]._SEG_NEXT_SEG_GINDEX

		TEST	ESI,ESI
		JNZ	L1$
		;
		;NOW START AGAIN WITH FIRST DIFFERENT SEGMENT
		;
L4$:
		MOV	ESI,FIRST_DIF_SEG_GINDEX
		XOR	EAX,EAX

		TEST	ESI,ESI
		JZ	L9$

		MOV	ECX,ESI
		CONVERT	ESI,ESI,SEGMENT_GARRAY
		ASSUME	ESI:PTR SEGMENT_STRUCT
		MOV	EDX,[ESI]._SEG_OS2_FLAGS

		MOV	FIRST_DIF_SEG_GINDEX,EAX
		MOV	LAST_DIF_SEG_GINDEX,EAX
		JMP	L2$

L9$:
		MOV	EAX,EBX
		RET

L5$:
		;
		;DIFFERENT FLAGS, STICK IN DIF LIST
		;
		MOV	EAX,LAST_DIF_SEG_GINDEX
		MOV	LAST_DIF_SEG_GINDEX,ECX

		TEST	EAX,EAX
		JZ	L6$

		CONVERT	EAX,EAX,SEGMENT_GARRAY
		ASSUME	EAX:PTR SEGMENT_STRUCT

		MOV	[EAX]._SEG_NEXT_SEG_GINDEX,ECX
L7$:
		XOR	ECX,ECX
		MOV	EAX,[ESI]._SEG_NEXT_SEG_GINDEX

		MOV	[ESI]._SEG_NEXT_SEG_GINDEX,ECX
		MOV	ESI,EAX

		TEST	EAX,EAX
		JNZ	L1$
		JMP	L4$

L6$:
		MOV	FIRST_DIF_SEG_GINDEX,ECX
		JMP	L7$

FINE_TUNE_SEGMENTS	ENDP


LINK_IN_4_LISTS PROC	NEAR
		;
		;LINK ANY SEGMENTS TO CORRECT LIST
		;
		MOV	ESI,FIRST_CLASS_GINDEX
		JMP	TEST_CLASS

CLASS_LOOP:
		MOV	EAX,tls_CLASS_GINDEX
		MOV	ECX,ESI

		CONVERT	ESI,ESI,CLASS_GARRAY
		ASSUME	ESI:PTR CLASS_STRUCT
		MOV	EBX,[ESI]._C_NEXT_CLASS_GINDEX
		CMP	EAX,ECX
		;
		;FIRST SEE IF IT IS A SPECIAL DEBUG TYPE
		;
		MOV	AL,[ESI]._C_TYPE_FLAG
		PUSH	EBX

		JZ	M_tls

		AND	AL,MASK SEG_CV_TYPES1 + MASK SEG_CV_SYMBOLS1
		JNZ	M_CV
DO_CLASS:
		CALL	LINK_SEGMENTS_4		;LINK SEGMENTS TO CORRECT LIST
NEXT_CLASS:
		POP	ESI
TEST_CLASS:
		TEST	ESI,ESI
		JNZ	CLASS_LOOP

		RET

M_tls:
		;
		;IF PE OUTPUT, DO SPECIAL TLS SUPPORT
		;
		GETT	BL,OUTPUT_PE

		TEST	BL,BL
		JZ	DO_CLASS

		SETT	GOT_tls_CLASS,BL
		JMP	NEXT_CLASS

M_CV:
		CALL	STORE_DEBUG_CLASS

		POP	ESI
		JMP	TEST_CLASS

LINK_IN_4_LISTS ENDP


LINK_SEGMENTS_4	PROC	NEAR
		;
		;LINK THE SEGMENTS IN THIS CLASS INTO SEVERAL POSSIBLE LISTS
		;
		;CX:DS:SI IS CLASS PTR
		;
		;
		;IF REORDER_ALLOWED:
		;
		;  LIST 1		NON-GROUPED CODE SEGMENTS
		;  LIST 2		GROUPED CODE SEGMENTS
		;  LIST 3		NON-GROUPED DATA SEGMENTS
		;  LIST 4		GROUPED DATA SEGMENTS
		;  LIST 5		DGROUP
		;
		;IF NO REORDER_ALLOWED:
		;
		;  IF DOSSEG
		;
		;    LIST 1		ANY CODE SEGMENTS

		;    LIST 3		ANY NON-DGROUP SEGMENTS
		;    LIST 4		ANY DGROUP SEGMENTS
		;
		;  IF NODOSSEG
		;
		;    LIST 1		ANY SEGMENTS
		;
		;
		ADD	ESI,CLASS_STRUCT._C_FIRST_SEG_GINDEX-SEGMENT_STRUCT._SEG_NEXT_SEG_GINDEX
		ASSUME	ESI:PTR SEGMENT_STRUCT
NEXT_SEG:
		XOR	EBX,EBX
		MOV	ECX,[ESI]._SEG_NEXT_SEG_GINDEX

		MOV	[ESI]._SEG_NEXT_SEG_GINDEX,EBX
		MOV	ESI,ECX

		TEST	ECX,ECX
		JZ	L9$

		CONVERT	ESI,ESI,SEGMENT_GARRAY

		MOV	EDX,[ESI]._SEG_FIRST_SEGMOD_GINDEX		;UNLINK ANY NOT REALLY HERE...
		MOV	AL,[ESI]._SEG_TYPE

		TEST	EDX,EDX
		JZ	NEXT_SEG

		TEST	AL,MASK SEG_CLASS_IS_CODE
		JNZ	CODE_SEGMENT
		;
		;THIS IS A DATA SEGMENT, IS IT GROUPED?
		;
		MOV	EDI,[ESI]._SEG_GROUP_GINDEX

		TEST	EDI,EDI
		JNZ	GROUPED_DATA
		;
		;UNGROUPED DATA SEGMENT
		;
UNGROUPED_DATA:
		MOV	EBX,SEGMENT_COUNT
		MOV	AL,[ESI]._SEG_32FLAGS

		INC	EBX
		TEST	AL,MASK SEG32_NONZERO

		MOV	SEGMENT_COUNT,EBX
		JNZ	SEG_NONZERO

		INC	ZERO_LENGTH_SEGMENTS
SEG_NONZERO:
		GETT	AL,REORDER_ALLOWED
		GETT	BL,DOSSEG_FLAG

		OR	AL,AL
		JNZ	DATA_NORMAL

		OR	BL,BL
		JZ	CODE_NORMAL
DATA_NORMAL:
		MOV	EAX,LAST_DATA_SEGMENT_GINDEX
		MOV	LAST_DATA_SEGMENT_GINDEX,ECX

		TEST	EAX,EAX
		JZ	DO_FIRST_DATA_SEGMENT

		CONVERT	EAX,EAX,SEGMENT_GARRAY
		ASSUME	EAX:PTR SEGMENT_STRUCT

		MOV	[EAX]._SEG_NEXT_SEG_GINDEX,ECX
		JMP	NEXT_SEG

DO_FIRST_DATA_SEGMENT:
		MOV	FIRST_DATA_SEGMENT_GINDEX,ECX
		JMP	NEXT_SEG

L9$:
		RET


GROUPED_DATA:
		MOV	EBX,EDI			;SAVE FOR GROUP ORDERING IF ALLOWED
		CONVERT	EDI,EDI,GROUP_GARRAY
		ASSUME	EDI:PTR GROUP_STRUCT
		MOV	EDX,[EDI]._G_LAST_SEG_GINDEX

		TEST	EDX,EDX
		JZ	GRP_DAT_FIRST

		MOV	AL,[EDI]._G_TYPE1

		TEST	AL,MASK GROUP_IS_CODE
		JZ	GRPTYP_OK

		CALL	GRP_TYP_ERROR		;COMPLAIN IF PROTECTED MODE

GRPTYP_OK:
		MOV	EAX,[EDI]._G_OS2_FLAGS
		MOV	[EDI]._G_LAST_SEG_GINDEX,ECX
		;
		;SET ANY BITS IN OS2_FLAGS THAT MIGHT NOT BE SET YET...
		;
		XOR	EAX,[ESI]._SEG_OS2_FLAGS

		AND	EAX,NOT MASK SR_MULTIPLE
		JZ	FLAGS_OK

		CALL	FE_ROUTINE
FLAGS_OK:

		CALL	CHECK_USE1632_GROUP

		GETT	AL,REORDER_ALLOWED
		GETT	BL,DOSSEG_FLAG

		TEST	AL,AL
		JNZ	DATA_GROUP_REORDER

		TEST	BL,BL
		JZ	CODE_NORMAL

		MOV	AL,[ESI]._SEG_TYPE

		TEST	AL,MASK SEG_IN_DGROUP
		JZ	DATA_NORMAL

DATA_GROUP_REORDER:
		CONVERT	EDX,EDX,SEGMENT_GARRAY
		ASSUME	EDX:PTR SEGMENT_STRUCT

		MOV	[EDX]._SEG_NEXT_SEG_GINDEX,ECX
		JMP	NEXT_SEG

GRP_DAT_FIRST:
		;
		;FIRST SEGMENT THIS GROUP
		;
		OR	[EDI]._G_TYPE1,MASK GROUP_IS_DATA

		TEST	[ESI]._SEG_TYPE,MASK SEG_IN_DGROUP
		JNZ	DONT_LINK_DGROUP
		;
		;LINK THIS GROUP TO DATA GROUP LIST
		;
		MOV	EAX,LAST_DATA_GROUP_GINDEX
		MOV	LAST_DATA_GROUP_GINDEX,EBX

		TEST	EAX,EAX
		JZ	DO_FIRST_DATA_GROUP

		CONVERT	EAX,EAX,GROUP_GARRAY
		ASSUME	EAX:PTR GROUP_STRUCT

		MOV	[EAX]._G_NEXT_GROUP_GINDEX,EBX

DFDG_RET:
DONT_LINK_DGROUP:

		XOR	EBX,EBX
		INC	SEGMENT_COUNT

		MOV	EAX,[ESI]._SEG_OS2_FLAGS
		MOV	[EDI]._G_NEXT_GROUP_GINDEX,EBX

		MOV	[EDI]._G_OS2_FLAGS,EAX
		MOV	[EDI]._G_FIRST_SEG_GINDEX,ECX

		MOV	[EDI]._G_LAST_SEG_GINDEX,ECX
		CALL	SET_USE1632_GROUP

		GETT	AL,REORDER_ALLOWED
		GETT	BL,DOSSEG_FLAG

		OR	AL,AL
		JNZ	DNS

		OR	BL,BL
		JZ	CODE_NORMAL

		MOV	AL,[ESI]._SEG_TYPE

		TEST	AL,MASK SEG_IN_DGROUP
		JZ	DATA_NORMAL
DNS:
		JMP	NEXT_SEG

DO_FIRST_DATA_GROUP:
		MOV	FIRST_DATA_GROUP_GINDEX,EBX
		JMP	DFDG_RET

CODE_SEGMENT:
		;
		;THIS IS A CODE SEGMENT, IS IT GROUPED?
		;
		MOV	EDI,[ESI]._SEG_GROUP_GINDEX

		TEST	EDI,EDI
		JNZ	GROUPED_CODE
		;
		;UNGROUPED CODE SEGMENT
		;
		MOV	EBX,SEGMENT_COUNT
		MOV	AL,[ESI]._SEG_32FLAGS

		INC	EBX
		TEST	AL,MASK SEG32_NONZERO

		MOV	SEGMENT_COUNT,EBX
		JNZ	CSEG_NZERO

		INC	ZERO_LENGTH_SEGMENTS
CSEG_NZERO:

CODE_NORMAL:
		MOV	EAX,LAST_CODE_SEGMENT_GINDEX
		MOV	LAST_CODE_SEGMENT_GINDEX,ECX

		TEST	EAX,EAX
		JZ	DO_FIRST_CODE_SEGMENT

		CONVERT	EAX,EAX,SEGMENT_GARRAY
		ASSUME	EAX:PTR SEGMENT_STRUCT

		MOV	[EAX]._SEG_NEXT_SEG_GINDEX,ECX
		JMP	NEXT_SEG

DO_FIRST_CODE_SEGMENT:
		MOV	FIRST_CODE_SEGMENT_GINDEX,ECX
		JMP	NEXT_SEG


GROUPED_CODE:
		;
		;
		;
		MOV	EBX,EDI
		CONVERT	EDI,EDI,GROUP_GARRAY
		ASSUME	EDI:PTR GROUP_STRUCT
		MOV	EDX,[EDI]._G_LAST_SEG_GINDEX

		TEST	EDX,EDX
		JZ	GRP_COD_FIRST

		MOV	AL,[EDI]._G_TYPE1

		TEST	AL,MASK GROUP_IS_DATA
		JZ	CGRPTYP_OK

		CALL	GRP_TYP_ERROR

CGRPTYP_OK:

		MOV	EAX,[EDI]._G_OS2_FLAGS
		MOV	[EDI]._G_LAST_SEG_GINDEX,ECX
		;
		;SET ANY BITS IN OS2_FLAGS THAT MIGHT NOT BE SET YET...
		;
		XOR	EAX,[ESI]._SEG_OS2_FLAGS

		AND	EAX,NOT MASK SR_MULTIPLE
		JZ	CFLAGS_OK

		CALL	FE_ROUTINE

CFLAGS_OK:

		CALL	CHECK_USE1632_GROUP

		GETT	AL,REORDER_ALLOWED
		GETT	BL,DOSSEG_FLAG

		TEST	AL,AL
		JNZ	CODE_GROUP_REORDER

		TEST	BL,BL
		JZ	CODE_NORMAL

		MOV	AL,[ESI]._SEG_TYPE

		TEST	AL,MASK SEG_IN_DGROUP
		JZ	CODE_NORMAL

CODE_GROUP_REORDER:
		CONVERT	EDX,EDX,SEGMENT_GARRAY
		MOV	[EDX]._SEG_NEXT_SEG_GINDEX,ECX
		JMP	NEXT_SEG

GRP_COD_FIRST:
		;
		;FIRST SEGMENT THIS GROUP
		;
		OR	[EDI]._G_TYPE1,MASK GROUP_IS_CODE	;MARK GROUP AS 'CODE' TYPE

		TEST	[ESI]._SEG_TYPE,MASK SEG_IN_DGROUP
		JNZ	DONT_LINK_CDGROUP			;IN CASE OF CODE IN DGROUP...
		;
		;LINK THIS GROUP TO CODE GROUP LIST
		;
		MOV	EAX,LAST_CODE_GROUP_GINDEX
		MOV	LAST_CODE_GROUP_GINDEX,EBX

		TEST	EAX,EAX
		JZ	DO_FIRST_CODE_GROUP

		CONVERT	EAX,EAX,GROUP_GARRAY
		ASSUME	EAX:PTR GROUP_STRUCT

		MOV	[EAX]._G_NEXT_GROUP_GINDEX,EBX

DFCG_RET:
DONT_LINK_CDGROUP:

		XOR	EBX,EBX
		INC	SEGMENT_COUNT

		MOV	EAX,[ESI]._SEG_OS2_FLAGS
		MOV	[EDI]._G_NEXT_GROUP_GINDEX,EBX

		MOV	[EDI]._G_OS2_FLAGS,EAX
		MOV	[EDI]._G_FIRST_SEG_GINDEX,ECX

		MOV	[EDI]._G_LAST_SEG_GINDEX,ECX
		CALL	SET_USE1632_GROUP

		GETT	AL,REORDER_ALLOWED
		GETT	BL,DOSSEG_FLAG

		OR	AL,AL
		JNZ	CNS

		OR	BL,BL
		JZ	CODE_NORMAL

		MOV	AL,[ESI]._SEG_TYPE

		TEST	AL,MASK SEG_IN_DGROUP
		JZ	CODE_NORMAL
CNS:
		JMP	NEXT_SEG

DO_FIRST_CODE_GROUP:
		MOV	FIRST_CODE_GROUP_GINDEX,EBX
		JMP	DFCG_RET

GRP_TYP_ERROR:

		GETT	BL,OUTPUT_SEGMENTED
		MOV	AL,GRP_COD_DAT_ERR

		OR	BL,BL
		JZ	GTE_9

		PUSH	ECX
		LEA	ECX,[EDI]._G_TEXT

		CALL	ERR_ASCIZ_RET
		POP	ECX
GTE_9:
		RET


FE_ROUTINE::
		PUSHM	ECX,EBX

		MOV	ECX,[ESI]._SEG_OS2_FLAGS
		MOV	EBX,[EDI]._G_OS2_FLAGS

		OR	ECX,EAX
		OR	EBX,EAX

		MOV	[ESI]._SEG_OS2_FLAGS,ECX
		MOV	[EDI]._G_OS2_FLAGS,EBX

		GETT	AL,OS2_FLAGS_DIFFERED
		POP	EBX

		TEST	AL,AL
		JNZ	FE_1

		SETT	OS2_FLAGS_DIFFERED

		BITT	OUTPUT_SEGMENTED		;REPORT IF SEGMENTED OUTPUT
		JNZ	FE_R_YES

		BITT	OUTPUT_PE			;REPORT IF PE OUTPUT
		JNZ	FE_R_YES

FE_1:
		POP	ECX
		RET

FE_R_YES:
		MOV	AL,OS2_FLAG_CONFLICT_ERR

		LEA	ECX,[EDI]._G_TEXT
		CALL	WARN_ASCIZ_RET
		JMP	FE_1


LINK_SEGMENTS_4	ENDP


MAKE_OS2_MATCH	PROC	NEAR
		;
		;
		;
		MOV	ESI,FIRST_GROUP_GINDEX
		JMP	TEST_GROUP

L1$:
		CONVERT	ESI,ESI,GROUP_GARRAY
		ASSUME	ESI:PTR GROUP_STRUCT

		MOV	EAX,[ESI]._G_NEXT_GROUP_GINDEX
		MOV	EBX,[ESI]._G_OS2_FLAGS	;FORCE THIS ON ALL...

		PUSH	EAX
		MOV	EDX,[ESI]._G_LAST_SEG_GINDEX

		MOV	ESI,[ESI]._G_FIRST_SEG_GINDEX
		JMP	TEST_SEG

L2$:
		MOV	ECX,ESI
		CONVERT	ESI,ESI,SEGMENT_GARRAY
		ASSUME	ESI:PTR SEGMENT_STRUCT
		MOV	[ESI]._SEG_OS2_FLAGS,EBX

		CMP	ECX,EDX
		JZ	L4$

		MOV	ESI,[ESI]._SEG_NEXT_SEG_GINDEX

TEST_SEG:
		TEST	ESI,ESI
		JNZ	L2$
L4$:
		POP	ESI
TEST_GROUP:
		TEST	ESI,ESI
		JNZ	L1$

		RET

MAKE_OS2_MATCH	ENDP


LINK_4_TOGETHER	PROC	NEAR
		;
		;MERGE FOUR LISTS INTO ONE FINAL SEGMENT LIST
		;
		XOR	EAX,EAX
		MOV	FIRST_SEGMENT_GINDEX,EAX

		BITT	REORDER_ALLOWED
		JZ	L1$

		MOV	EAX,FIRST_CODE_GROUP_GINDEX	;SEGMENTS LINKED HERE IF REORDERING
		CALL	LINK_GROUPS
L1$:

		MOV	EAX,FIRST_CODE_SEGMENT_GINDEX
		MOV	ECX,LAST_CODE_SEGMENT_GINDEX
		CALL	LINK_SEGMENTS
if	fg_pe
		CALL	LINK_tls
endif
		MOV	EAX,FIRST_DATA_SEGMENT_GINDEX
		MOV	ECX,LAST_DATA_SEGMENT_GINDEX
		CALL	LINK_SEGMENTS

		BITT	REORDER_ALLOWED
		JZ	L5$

		MOV	EAX,FIRST_DATA_GROUP_GINDEX	;SEGMENTS LINKED HERE IF REORDERING
		CALL	LINK_GROUPS
		JMP	L6$

L5$:
		;
		;IF REORDER OR DOSSEG, ADD IN DGROUP, PUT GROUPS BACK TOGETHER
		;
		BITT	DOSSEG_FLAG
		JZ	L7$
L6$:
		MOV	ESI,DGROUP_GINDEX

		TEST	ESI,ESI
		JZ	L7$

		CONVERT	ESI,ESI,GROUP_GARRAY
		ASSUME	ESI:PTR GROUP_STRUCT

		MOV	ECX,[ESI]._G_LAST_SEG_GINDEX
		MOV	EAX,[ESI]._G_FIRST_SEG_GINDEX

		CALL	LINK_SEGMENTS
L7$:
		;
		;PUT GROUPS BACK TOGETHER
		;
		XOR	EAX,EAX
		MOV	LAST_GROUP_GINDEX,EAX

		MOV	EAX,FIRST_CODE_GROUP_GINDEX
		MOV	ECX,LAST_CODE_GROUP_GINDEX
		CALL	ADD_TO_GROUPS

		MOV	EAX,FIRST_DATA_GROUP_GINDEX
		MOV	ECX,LAST_DATA_GROUP_GINDEX
		CALL	ADD_TO_GROUPS

		MOV	EAX,DGROUP_GINDEX
		MOV	EDX,LAST_GROUP_GINDEX

		TEST	EAX,EAX
		JZ	L9$

		MOV	LAST_GROUP_GINDEX,EAX

		TEST	EDX,EDX
		JZ	L8$

		CONVERT	EDX,EDX,GROUP_GARRAY
		ASSUME	EDX:PTR GROUP_STRUCT

		MOV	[EDX]._G_NEXT_GROUP_GINDEX,EAX
L9$:
		RET

L8$:
		MOV	FIRST_GROUP_GINDEX,EAX
		RET

LINK_4_TOGETHER	ENDP


FIX_MIDGROUPS	PROC	NEAR
		;
		;ALLOCATE INTERMEDIATE SEGMENTS TO GROUPS
		;
		;OK, SCAN THROUGH SEGMENTS TILL WE FIND A SEGMENT IN A GROUP.
		;ADD THAT SEGMENT TO THE GROUP (FIRST_SEG)
		;CONTINUE FROM THERE TILL YOU REACH LAST_SEG, ADDING ANY INTERMEDIATE SEGMENTS
		;TO THE GROUP.
		;
		PUSH	EBP
		MOV	ESI,FIRST_SEGMENT_GINDEX
L1$:
		;
		;IN THIS LOOP, WE ARE SEARCHING FOR THE NEXT SEGMENT THAT BELONGS TO A GROUP
		;
		TEST	ESI,ESI
		JZ	L19$

		MOV	ECX,ESI
		CONVERT	ESI,ESI,SEGMENT_GARRAY
		ASSUME	ESI:PTR SEGMENT_STRUCT

		MOV	EDI,[ESI]._SEG_GROUP_GINDEX
		MOV	ESI,[ESI]._SEG_NEXT_SEG_GINDEX

		TEST	EDI,EDI
		JZ	L1$			;NO GROUP, JUMP
L2$:
		;
		;FOUND SEGMENT THAT HAS A GROUP
		;SCAN TILL LAST SEGMENT OF GROUP
		;ERROR ON GROUP MISMATCH
		;
		MOV	EBX,ESI
		MOV	EDX,EDI

		CONVERT	EDI,EDI,GROUP_GARRAY
		ASSUME	EDI:PTR GROUP_STRUCT

		MOV	EBP,[EDI]._G_LAST_SEG_GINDEX
L31$:
		MOV	ESI,EBX
L32$:
		CMP	EBP,ECX		;WAS THIS LAST SEG IN GROUP?
		JZ	L1$

		MOV	ECX,ESI
		CONVERT	ESI,ESI,SEGMENT_GARRAY
		ASSUME	ESI:PTR SEGMENT_STRUCT

		MOV	EBX,[ESI]._SEG_GROUP_GINDEX
		MOV	ESI,[ESI]._SEG_NEXT_SEG_GINDEX

		CMP	EBX,EDX
		JZ	L32$
L35$:
		;
		;SPECIAL CASES:  IF NOT A GROUP MEMBER, MAKE IT A MEMBER OF CURRENT GROUP
		;
		TEST	EBX,EBX
		JNZ	L4$			;NOPE, MUST BE A GROUP OVERLAP...

		MOV	EBX,ESI
		CONVERT	ESI,ECX,SEGMENT_GARRAY
		ASSUME	ESI:PTR SEGMENT_STRUCT

		DEC	SEGMENT_COUNT		;UNDO SEGMENT COUNTING NONSENSE
		MOV	[ESI]._SEG_GROUP_GINDEX,EDX

		TEST	[ESI]._SEG_32FLAGS,MASK SEG32_NONZERO
		JNZ	SEG_NONZERO
		DEC	ZERO_LENGTH_SEGMENTS
SEG_NONZERO:
		;
		;MAKE SURE CODE VS DATA MATCHES
		;
		;
		;NOW MARK FLAGS
		;
		MOV	EAX,[EDI]._G_OS2_FLAGS
		XOR	EAX,[ESI]._SEG_OS2_FLAGS
		AND	EAX,NOT MASK SR_MULTIPLE
		JZ	FLAGS_OK

		CALL	FE_ROUTINE
FLAGS_OK:
		;
		;IF GROUP IS DGROUP, MARK ALL SEGMODS...
		;
		CMP	DGROUP_GINDEX,EDX
		JNZ	L31$
		;
		;IF SEGMENT NOT ALREADY MARKED, MARK IT AND ANY SEGMODS.
		;
		OR	[ESI]._SEG_TYPE,MASK SEG_IN_DGROUP
		PUSH	ECX
		MOV	ESI,[ESI]._SEG_FIRST_SEGMOD_GINDEX
		JMP	L37$

L19$:
		POP	EBP
		RET

L36$:
		CONVERT	ESI,ESI,SEGMOD_GARRAY
		ASSUME	ESI:PTR SEGMOD_STRUCT

		OR	[ESI]._SM_FLAGS,MASK SEG_IN_DGROUP
		MOV	ESI,[ESI]._SM_NEXT_SEGMOD_GINDEX
L37$:
		TEST	ESI,ESI
		JNZ	L36$

		POP	ECX
		CONVERT	ESI,ECX,SEGMENT_GARRAY
		ASSUME	ESI:PTR SEGMENT_STRUCT
		JMP	L31$

L4$:
		;
		;GROUP OVERLAP - IRRELEVANT IN REAL MODE...
		;

		BITT	OUTPUT_SEGMENTED
		JZ	L49$

		MOV	AL,GRP_OVERLAP_ERR
		CALL	ERR_RET

L49$:
		JMP	L2$

FIX_MIDGROUPS	ENDP


ADD_TO_GROUPS	PROC	NEAR
		;
		;EAX IS FIRST, ECX IS LAST
		;
		TEST	ECX,ECX
		JZ	L9$
		;
		;DO FIRST GROUP
		;
		MOV	EDX,LAST_GROUP_GINDEX
		MOV	LAST_GROUP_GINDEX,ECX

		TEST	EDX,EDX
		JZ	L6$

		CONVERT	EDX,EDX,GROUP_GARRAY
		ASSUME	EDX:PTR GROUP_STRUCT

		MOV	[EDX]._G_NEXT_GROUP_GINDEX,EAX
L9$:
		RET

L6$:
		MOV	FIRST_GROUP_GINDEX,EAX
		RET

ADD_TO_GROUPS	ENDP

if	fg_pe

LINK_tls	PROC
		;
		;ADD tls SEGMENTS IF ANY
		;
		GETT	AL,GOT_tls_CLASS
		MOV	ECX,tls_CLASS_GINDEX

		TEST	AL,AL
		JZ	L9$
		;
		;SORT ALPHABETICALLY?  MAYBE TOMORROW...
		;
		CONVERT	ECX,ECX,CLASS_GARRAY
		ASSUME	ECX:PTR CLASS_STRUCT

		MOV	EAX,[ECX]._C_FIRST_SEG_GINDEX
		MOV	ECX,[ECX]._C_LAST_SEG_GINDEX

		JMP	LINK_SEGMENTS

		ASSUME	ECX:NOTHING

L9$:
		RET

LINK_tls	ENDP

endif


LINK_SEGMENTS	PROC	NEAR
		;
		;EAX IS FIRST, ECX IS LAST
		;CX IS FIRST, DX IS LAST
		;
		TEST	EAX,EAX
		JZ	L9$

		MOV	EDX,LAST_SEGMENT_GINDEX
		MOV	LAST_SEGMENT_GINDEX,ECX

		TEST	EDX,EDX
		JZ	L5$

		CONVERT	EDX,EDX,SEGMENT_GARRAY
		ASSUME	EDX:PTR SEGMENT_STRUCT

		MOV	[EDX]._SEG_NEXT_SEG_GINDEX,EAX
L9$:
		RET

L5$:
		MOV	FIRST_SEGMENT_GINDEX,EAX
		RET

LINK_SEGMENTS	ENDP


LINK_GROUPS	PROC	NEAR


		MOV	EDX,EAX
		JMP	TEST_GROUP

L1$:
		CONVERT	EDX,EDX,GROUP_GARRAY
		ASSUME	EDX:PTR GROUP_STRUCT

		MOV	EAX,[EDX]._G_NEXT_GROUP_GINDEX
		MOV	ECX,[EDX]._G_LAST_SEG_GINDEX

		PUSH	EAX
		MOV	EAX,[EDX]._G_FIRST_SEG_GINDEX

		CALL	LINK_SEGMENTS

		POP	EDX
TEST_GROUP:
		TEST	EDX,EDX
		JNZ	L1$
		RET

LINK_GROUPS	ENDP


SET_USE1632_GROUP	PROC	NEAR
		;
		;
		;
		MOV	AL,[ESI]._SEG_32FLAGS
		MOV	BL,[EDI]._G_TYPE1

		TEST	AL,MASK SEG32_USE16
		JZ	L2$

		OR	BL,MASK GROUP_IS_USE16

		MOV	[EDI]._G_TYPE1,BL

		RET

L2$:
		TEST	AL,MASK SEG32_USE32
		JZ	L4$

		OR	BL,MASK GROUP_IS_USE32

		MOV	[EDI]._G_TYPE1,BL
L4$:
		RET

SET_USE1632_GROUP	ENDP


CHECK_USE1632_GROUP	PROC	NEAR
		;
		;
		;
		MOV	AL,[EDI]._G_TYPE1
		MOV	BL,[ESI]._SEG_32FLAGS

		TEST	AL,MASK GROUP_IS_USE16+MASK GROUP_IS_USE32
		JZ	SET_USE1632_GROUP

		TEST	BL,MASK SEG32_USE16

		JZ	L2$

		TEST	AL,MASK GROUP_IS_USE32
		JNZ	L8$

		RET

L2$:
		AND	BL,MASK SEG32_USE32
		JZ	L4$

		TEST	AL,MASK GROUP_IS_USE16
		JNZ	L8$
L4$:
		RET

L8$:
		PUSH	ECX
		MOV	AL,USE32_USE16_ERR

		LEA	ECX,[EDI]._G_TEXT
		CALL	WARN_ASCIZ_RET

		POP	ECX
		RET

CHECK_USE1632_GROUP	ENDP


		.DATA

		ALIGN	4


DOSSEG_STUFF	DD	BEGDATA_CLASS_GINDEX
		DD	BSS_CLASS_GINDEX
		DD	STACK_CLASS_GINDEX
		DD	ZERO
ZERO		DD	0


		END

